﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AlarmClock.BLL
{
    public class Service
    {
        #region 实体信息转显示信息【Entity -> Model】

        /// <summary>
        /// 1.1【闹钟】实体信息转显示信息
        /// </summary>
        /// <param name="barKanbans"></param>
        /// <returns></returns>
        public static Model.Clock ClockToModel(Entity.Clock EntityClock)
        {
            return new Model.Clock()
            {
                ClockName = EntityClock.ClockName,
                clockInfo = new Model.ClockInfo()
                {
                    time = EntityClock.ClockInfo.time,
                    repeat = EntityClock.ClockInfo.repeat,
                    music = EntityClock.ClockInfo.music,
                    things = EntityClock.ClockInfo.things,
                    nextInterval = EntityClock.ClockInfo.nextInterval,
                    musicVolume = EntityClock.ClockInfo.musicVolume,
                    musicPlus = EntityClock.ClockInfo.musicPlus,
                    isActive = EntityClock.ClockInfo.isActive,
                }
            };
        }

        /// <summary>
        /// 1.2【闹钟集合】实体信息转显示信息
        /// </summary>
        /// <param name="EntityClockList"></param>
        /// <returns></returns>
        public static List<Model.Clock> ClockListToModel(List<Entity.Clock> EntityClockList)
        {
            List<Model.Clock> clockList = new List<Model.Clock>();

            foreach (var clock in EntityClockList)
                clockList.Add(ClockToModel(clock));

            return clockList;
        }

        /// <summary>
        /// 1.3【闹钟全局配置】实体信息转显示信息
        /// </summary>
        /// <param name="EntityClockConfig"></param>
        /// <returns></returns>
        public static Model.ClockConfig ClockConfigToModel(Entity.ClockConfig EntityClockConfig)
        {
            return new Model.ClockConfig()
            {
                recentTime = EntityClockConfig.recentTime,
                clockCount = EntityClockConfig.clockCount,
                clockMaxNum = EntityClockConfig.clockMaxNum,
                appAutoStart = EntityClockConfig.appAutoStart,
                alarmingShowWeather = EntityClockConfig.alarmingShowWeather,
                isExitToMiniMode=EntityClockConfig.isExitToMiniMode,
                createDeskShortCut=EntityClockConfig.createDeskShortCut,
            };
        }

        #endregion

        #region 显示信息转实体信息【Model -> Entity】

        /// <summary>
        /// 2.1【闹钟】显示信息转实体信息
        /// </summary>
        /// <param name="barKanbans"></param>
        /// <returns></returns>
        public static Entity.Clock ClockToEntity(Model.Clock ModelClock)
        {
            return new Entity.Clock()
            {
                ClockName = ModelClock.ClockName,
                ClockInfo = new Entity.ClockInfo()
                {
                    time = ModelClock.clockInfo.time,
                    repeat = ModelClock.clockInfo.repeat,
                    music = ModelClock.clockInfo.music,
                    things = ModelClock.clockInfo.things,
                    nextInterval = ModelClock.clockInfo.nextInterval,
                    musicVolume = ModelClock.clockInfo.musicVolume,
                    musicPlus = ModelClock.clockInfo.musicPlus,
                    isActive = ModelClock.clockInfo.isActive,
                }
            };
        }

        /// <summary>
        /// 2.2【闹钟集合】显示信息转实体信息
        /// </summary>
        /// <param name="EntityClockList"></param>
        /// <returns></returns>
        public static List<Entity.Clock> ClockListToEntity(List<Model.Clock> ModelClockList)
        {
            List<Entity.Clock> clockList = new List<Entity.Clock>();

            foreach (var clock in ModelClockList)
                clockList.Add(ClockToEntity(clock));

            return clockList;
        }

        /// <summary>
        /// 2.3【闹钟全局配置】显示信息转实体信息
        /// </summary>
        /// <param name="EntityClockConfig"></param>
        /// <returns></returns>
        public static Entity.ClockConfig ClockConfigToEntity(Model.ClockConfig ModelClockConfig)
        {
            return new Entity.ClockConfig()
            {
                recentTime = ModelClockConfig.recentTime,
                clockCount = ModelClockConfig.clockCount,
                clockMaxNum = ModelClockConfig.clockMaxNum,
                appAutoStart = ModelClockConfig.appAutoStart,
                isExitToMiniMode = ModelClockConfig.isExitToMiniMode,
                alarmingShowWeather = ModelClockConfig.alarmingShowWeather,
                createDeskShortCut = ModelClockConfig.createDeskShortCut,
            };
        }

        #endregion

        #region 枚举常量

        public static class Constant
        {
            //常量-音量
            public const string ORDINARY = "普通";
            public const string STRONGLY = "强烈";
            public const string SOFT = "轻柔";

            //常量-天气

            // 常量-闹钟增删改查、稍后提醒
            public const string CLOCK_ADD = "增加闹钟";
            public const string CLOCK_DELETE = "删除闹钟";
            public const string CLOCK_UPDATE = "修改闹钟";
            public const string CLOCK_CLOSE = "关闭闹钟";
            public const string CLOCK_LATERALARMING = "稍后提醒";
        }

        #endregion

        /// <summary>
        /// 控制音量
        /// </summary>
        /// <param name="musicVolume"></param>
        /// <returns></returns>
        public static float GetAlarmVolume(string musicVolume)
        {
            float volume = 0.9f;
            switch (musicVolume)
            {
                case Constant.ORDINARY:
                    volume = 0.8f;
                    break;
                case Constant.STRONGLY:
                    volume = 1.0f;
                    break;
                case Constant.SOFT:
                    volume = 0.5f;
                    break;
                default:
                    break;
            }
            return volume;
        }

        /// <summary>
        /// 根据字符串获取本地天气GIF路径
        /// </summary>
        /// <param name="weather">天气GIF路径</param>
        /// <param name="alarmingShowWeather">是否显示天气GIF</param>
        /// <returns></returns>
        public static string GetWeatherGIFPath(string weather, bool alarmingShowWeather = true)
        {
            string path = Application.StartupPath + $"\\Resourse\\Picture\\Weather\\{weather}.gif";

            if (!File.Exists(path))
            {
                path = Application.StartupPath + $"\\Resourse\\Picture\\Weather\\未知天气.png";
            }

            if (!File.Exists(path) || !alarmingShowWeather)
            {
                path = Application.StartupPath + @"\Resourse\Picture\闹钟动图.gif";
            }
            return path;
        }

        /// <summary>
        /// 切换音乐
        /// </summary>
        /// <param name="musicName"></param>
        /// <returns></returns>
        public static string GetMusicPath(string musicName)
        {
            try
            {
                string musicPath = Path.Combine(Application.StartupPath, $"Resourse\\Audio\\{musicName}");
                StreamReader streamReader = new StreamReader(musicPath);
                streamReader.Close();
                streamReader.Dispose();
                return musicPath;
            }
            catch (Exception ex)
            {
                Service.ExceptionTraceLog(ex);
                return Path.Combine(Application.StartupPath, @"Resourse\Audio\默认.mp3");
            }
        }

        /// <summary>
        /// 缩小图片成固定大小
        /// </summary>
        /// <param name="originalImage">原始图像</param>
        /// <param name="width">宽</param>
        /// <param name="height">高</param>
        /// <returns>处理后的图像</returns>
        public static Image ToResize(Image originalImage, int width, int height)
        {
            if (originalImage == null) return null;

            Bitmap newImage = new Bitmap(width, height);
            using (Graphics graphics = Graphics.FromImage(newImage))
            {
                graphics.DrawImage(originalImage, new Rectangle(0, 0, width, height));
                originalImage?.Dispose();
            }
            return newImage;
        }

        /// <summary>
        /// 设置鼠标悬浮panel效果
        /// </summary>
        /// <param name="tagertCtrl">设置目标控件效果</param>
        /// <param name="ctrl">迭代子控件</param>
        public static void SetControlsStyle(Control tagertCtrl, Control ctrl)
        {
            foreach (Control c in ctrl.Controls)
            {
                if (c == null) return;
                SetControlsStyle(tagertCtrl, c);
                c.MouseHover += (s1, e1) => { tagertCtrl.BackColor = Color.LightSteelBlue; };
                c.MouseLeave += (s1, e1) => { tagertCtrl.BackColor = Color.White; };
            }
        }

        /// <summary>
        /// 设置控件透明度
        /// </summary>
        /// <param name="ctrl">控件</param>
        public static void SetControlTransparent(Control ctrl,Control parent)
        {
            ctrl.BackColor = Color.Transparent;//设置控件的背景色为透明
            ctrl.Parent = parent;
        }

        /// <summary>
        /// 创建一个快捷方式(用户级别)
        /// </summary>
        /// <param name="targetPath">目标程序路径.exe</param>
        /// <param name="shortcutPath">快捷方式放置路径.lnk</param>
        public static bool CreateShortcut(string targetPath, string shortcutPath)
        {
            try
            {
                var shellType = Type.GetTypeFromProgID("WScript.Shell");
                dynamic shell = Activator.CreateInstance(shellType);
                var shortcut = shell.CreateShortcut(shortcutPath);
                shortcut.TargetPath = targetPath;
                //shortcut.Arguments = "在路径后面追加的参数 空格分隔";
                //shortcut.Description = "备注信息";
                //shortcut.WindowStyle = FormWindowState.Normal;
                //shortcut.IconLocation = "图标路径";

                shortcut.Save();

                return true;
            }
            catch (Exception ex)
            {
                Service.ExceptionTraceLog(ex);
                return false;
            }
        }

        /// <summary>
        /// 自定义：写Log
        /// </summary>
        /// <param name="ex"></param>
        public static void ExceptionTraceLog(Exception ex)
        {
            var errMsg = $"\n[Error]:\r\nExType:{ex.GetType()}\r\nDeclaringType:{ex.TargetSite.DeclaringType.FullName}\r\nMethod:{ex.TargetSite.Name}\r\nExMessage:{ex.Message}\r\nExStack:\r\n{ex.StackTrace}";
            WriteLog(errMsg);
        }

        private static string log_directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConfigurationManager.AppSettings["log_directory"]);
        private static string log_filename = ConfigurationManager.AppSettings["log_filename"];

        private static void WriteLog(string errMsg)
        {
            try
            {
                if (!Directory.Exists(log_directory)) Directory.CreateDirectory(log_directory);
                string filePath = Path.Combine(log_directory, log_filename);

                using (FileStream fs = new FileStream(filePath, FileMode.Append))
                {
                    using (StreamWriter sw = new StreamWriter(fs))
                    {
                        sw.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")} {errMsg}");
                    }
                }
            }
            catch { }
        }


        /// <summary>
        /// 查看程序是否已经运行
        /// </summary>
        /// <returns></returns>
        public static Process GetExistProcess()
        {
            Process currentProcess = Process.GetCurrentProcess();//当前程序
            foreach (Process process1 in Process.GetProcessesByName(currentProcess.ProcessName))
            {
                //同名程序有2个或者2个以上
                if (process1.Id != currentProcess.Id)
                {
                    return process1;//返回另外一个同名程序的进程
                }
            }
            return null;
        }
    }
}
